package com.example.coursehub.service.impl;

import com.example.coursehub.entity.*;
import com.example.coursehub.repository.*;
import com.example.coursehub.service.StatisticsService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

import java.util.stream.Collectors;

@Service
@Transactional
public class StatisticsServiceImpl implements StatisticsService {

    private final CourseRepository courseRepository;
    private final ChapterRepository chapterRepository;
    private final MaterialRepository materialRepository;
    private final StudentChapterRepository studentChapterRepository;
    private final CourseStudentRepository courseStudentRepository;
    private final StudentMaterialRepository studentMaterialRepository;
    private final ClassesRepository classesRepository;
//    private final UserRepository userRepository;
    private final ClassesStudentRepository classesStudentRepository;
    private final ExerciseRepository exerciseRepository;
    private final StudentExerciseRepository studentExerciseRepository;

    public StatisticsServiceImpl(CourseRepository courseRepository,
                                 ChapterRepository chapterRepository,
                                 MaterialRepository materialRepository,
                                 StudentChapterRepository studentChapterRepository,
                                 CourseStudentRepository courseStudentRepository,
                                 StudentMaterialRepository studentMaterialRepository,
                                 ClassesRepository classesRepository,
                                 UserRepository userRepository,
                                 ClassesStudentRepository classesStudentRepository,
                                 ExerciseRepository exerciseRepository,
                                 StudentExerciseRepository studentExerciseRepository) {
        this.courseRepository = courseRepository;
        this.chapterRepository = chapterRepository;
        this.materialRepository = materialRepository;
        this.studentChapterRepository = studentChapterRepository;
        this.courseStudentRepository = courseStudentRepository;
        this.studentMaterialRepository = studentMaterialRepository;
        this.classesRepository = classesRepository;
//        this.userRepository = userRepository;
        this.classesStudentRepository = classesStudentRepository;
        this.exerciseRepository = exerciseRepository;
        this.studentExerciseRepository = studentExerciseRepository;
    }

    @Override
    public List<String> getChapterIdsByStudentAndCourse(String studentId, String courseId) {
        // 验证学生是否选修了该课程
        CourseStudentId id = new CourseStudentId();
        id.setUserId(studentId);
        id.setCourseId(courseId);

        if (!courseStudentRepository.existsById(id)) {
            throw new IllegalArgumentException("学生未选修该课程");
        }

        // 获取课程下的所有章节
        List<Chapter> courseChapters = chapterRepository.findByCourse_CourseId(courseId);

        // 获取学生学习过的章节
        List<StudentChapter> studentChapters = studentChapterRepository.findByUser_UserId(studentId);

        // 过滤出属于该课程的章节ID
        return studentChapters.stream()
                .map(StudentChapter::getChapter)
                .filter(courseChapters::contains)
                .map(Chapter::getChapterId)
                .collect(Collectors.toList());
    }

    @Override
    public List<String> getMaterialIdsByChapter(String chapterId) {
        return materialRepository.findByChapter_ChapterId(chapterId).stream()
                .map(Material::getMaterialId)
                .collect(Collectors.toList());
    }

    @Override
    public Chapter getChapterById(String chapterId) {
        return chapterRepository.findById(chapterId)
                .orElseThrow(() -> new IllegalArgumentException("章节不存在: " + chapterId));
    }

    @Override
    public Course getCourseById(String courseId) {
        return courseRepository.findById(courseId)
                .orElseThrow(() -> new IllegalArgumentException("课程不存在: " + courseId));
    }

    @Override
    public Material getMaterialById(String materialId) {
        return materialRepository.findById(materialId)
                .orElseThrow(() -> new IllegalArgumentException("资料不存在: " + materialId));
    }

    @Override
    public List<String> getChapterIdsByCourse(String courseId) {
        return chapterRepository.findByCourse_CourseId(courseId).stream()
                .map(Chapter::getChapterId)
                .collect(Collectors.toList());
    }

    @Override
    public int getCourseProgress(String courseId, String studentId) {
        // 验证学生是否选修了该课程
        CourseStudentId id = new CourseStudentId();
        id.setUserId(studentId);
        id.setCourseId(courseId);

        if (!courseStudentRepository.existsById(id)) {
            return 0; // 未选修该课程
        }

        List<Chapter> chapters = chapterRepository.findByCourse_CourseId(courseId);

        if (chapters.isEmpty()) {
            return 100; // 没有章节视为已完成
        }

        int totalChapters = chapters.size();
        int completedChapters = 0;

        for (Chapter chapter : chapters) {
            StudentChapterId studentChapterId = new StudentChapterId();
            studentChapterId.setUserId(studentId);
            studentChapterId.setChapterId(chapter.getChapterId());

            Optional<StudentChapter> studentChapter = studentChapterRepository.findById(studentChapterId);
            if (studentChapter.isPresent() && studentChapter.get().getIsFinished()) {
                completedChapters++;
            }
        }

        return (int) (((double) completedChapters / totalChapters) * 100);
    }

    @Override
    public int getChapterProgress(String chapterId, String studentId) {
        List<Material> materials = materialRepository.findByChapter_ChapterId(chapterId);

        if (materials.isEmpty()) {
            // 章节无资料时，直接通过 StudentChapter 表判断章节是否完成
            StudentChapterId id = new StudentChapterId();
            id.setUserId(studentId);
            id.setChapterId(chapterId);
            return studentChapterRepository.findById(id)
                    .filter(StudentChapter::getIsFinished)
                    .map(s -> 100)
                    .orElse(0);
        }

        int totalMaterials = materials.size();
        int completedMaterials = 0;

        // **新增逻辑**：通过 StudentMaterial 表查询学生对每个资料的完成状态
        for (Material material : materials) {
            StudentMaterialId smId = new StudentMaterialId();
            smId.setUserId(studentId);
            smId.setMaterialId(material.getMaterialId());

            // 查询学生是否完成该资料
            Optional<StudentMaterial> studentMaterial = studentMaterialRepository.findById(smId);
            if (studentMaterial.isPresent() && studentMaterial.get().getIsFinished()) {
                completedMaterials++;
            }
        }

        return (int) (((double) completedMaterials / totalMaterials) * 100);
    }

    @Override
    public int getMaterialProgress(String materialId, String studentId) {
        StudentMaterialId id = new StudentMaterialId();
        id.setUserId(studentId);
        id.setMaterialId(materialId);

        // 查询学生与资料的关联记录
        Optional<StudentMaterial> studentMaterial = studentMaterialRepository.findById(id);

        // 若存在记录且已完成，返回 100%；否则返回 0%
        return studentMaterial.map(sm -> sm.getIsFinished() ? 100 : 0).orElse(0);
    }

    @Override
    public int calculateClassCompletionRate(String classId) {
        // 1. 获取班级对应的课程ID
        Classes classe = classesRepository.findByClassesId(classId);
        String courseId = classe.getCourse().getCourseId();
        if (courseId == null) {
            throw new IllegalArgumentException("课程不存在");
        }

        // 2. 获取课程总章节数
        List<Chapter> allChapterIds = chapterRepository.findByCourse_CourseId(courseId);
        int totalChapters = allChapterIds.size();
        if (totalChapters == 0) {
            return 100; // 课程没有章节
        }

        // 3. 获取班级所有学生
        List<User> students = getStudentsByClassId(classId);
        if (students.isEmpty()) {
            return 0; // 班级没有学生
        }

        // 4. 计算所有学生的完成章节总数
        int totalFinishedChapters = 0;
        for (User student : students) {
            int finishedChapters = studentChapterRepository
                    .countByUser_UserIdAndChapter_Course_CourseIdAndIsFinishedTrue(student.getUserId(),courseId);
            totalFinishedChapters += finishedChapters;
        }

        // 5. 计算班级完成比例
        // 公式：(所有学生完成的章节总数) / (课程章节总数 × 学生总数)
        int totalStudents = students.size();
        return (int) ((totalFinishedChapters / (double) (totalChapters * totalStudents)) * 100);
    }

    // 通过classId获取该班级下的所有学生
    public List<User> getStudentsByClassId(String classesId) {
        List<ClassesStudent> classStudents = classesStudentRepository.findByClasses_ClassesId(classesId);
        return classStudents.stream()
                .map(ClassesStudent::getUser)
                .collect(Collectors.toList());
    }

    /**
     * 计算作业完成率（学生提交比例）
     *
     * @param exerciseId 作业ID
     * @return 完成率百分比（整数）
     */
    public int calculateExerciseCompletionRate(String exerciseId) {
        // 1. 获取作业信息及所属班级
        Exercise exercise = exerciseRepository.findById(exerciseId)
                .orElseThrow(() -> new IllegalArgumentException("作业不存在"));

        Classes classes = exercise.getClasses();
        if (classes == null) {
            throw new IllegalArgumentException("作业未关联到任何班级");
        }

        // 2. 获取班级学生总数
        List<ClassesStudent> students = classesStudentRepository.findByClasses_ClassesId(classes.getClassesId());
        if (students.isEmpty()) {
            return 0; // 班级没有学生
        }
        int totalStudents = students.size();

        // 3. 统计已提交该作业的学生数量
        int submittedCount = studentExerciseRepository.countByExercise_ExerciseIdAndState(
                exerciseId, "submitted");

        // 4. 计算提交比例
        return (int) ((submittedCount / (double) totalStudents) * 100);

    }


}